package com.funong.matrix.biz.user.domain;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.funong.matrix.biz.base.dao.SysUserDao;
import com.funong.matrix.biz.base.entity.*;
import com.funong.matrix.biz.power.domain.SysMenuDomainDao;
import com.funong.matrix.biz.power.domain.SysRolePermissionDomainDao;
import com.funong.matrix.biz.power.domain.SysRoleUserDomainDao;
import com.funong.matrix.biz.user.pojo.dto.ResetPasswordDTO;
import com.funong.matrix.biz.user.pojo.dto.UserDTO;
import com.funong.matrix.biz.user.pojo.dto.UserLoginDTO;
import com.funong.matrix.biz.user.pojo.dto.UserPermissionMenuDTO;
import com.funong.matrix.biz.user.pojo.vo.LoginVO;
import com.funong.matrix.core.base.FunongBaseEntity;
import com.funong.matrix.core.dto.QueryDTO;
import com.funong.matrix.core.dto.Result;
import com.funong.matrix.core.enums.IsDeletedEnum;
import com.funong.matrix.core.enums.StatusEnum;
import com.funong.matrix.core.enums.SystemIdEnum;
import com.funong.matrix.core.utils.JwtUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wanjialin
 * @version 1.0
 * @date 2023/5/18
 */

@Service
public class SysUserDomainDao {

    @Resource
    private SysUserDao sysUserDao;
    @Resource
    private SysDeptDomainDao sysDeptDomainDao;
    @Resource
    private SysCompanyDomainDao sysCompanyDomainDao;
    @Resource
    private SysRoleUserDomainDao sysRoleUserDomainDao;
    @Resource
    private SysMenuDomainDao sysMenuDomainDao;
    @Resource
    private SysRolePermissionDomainDao sysRolePermissionDomainDao;
    @Resource
    private JwtUtils jwtUtils;


    public Result queryUser(QueryDTO<UserDTO> queryDTO) {

        ObjectMapper mapper = new ObjectMapper();
        UserDTO userDTO = mapper.convertValue(queryDTO.getCondition(), UserDTO.class);


        if (StringUtils.isEmpty(userDTO.getCompanyCode())) {
            IPage<SysUserEntity> sysUserEntityIPage = sysUserDao.queryUser(queryDTO);
            return Result.page(sysUserEntityIPage, queryUserDTOS(sysUserEntityIPage));
        }

        //根据code查询部门
        SysDeptEntity sysDeptEntity = sysDeptDomainDao.queryDeptAllByCode(userDTO.getCompanyCode());
        if (null != sysDeptEntity) {
            userDTO.setDeptCode(userDTO.getCompanyCode())
                    .setCompanyCode("");
            queryDTO.setCondition(userDTO);
            IPage<SysUserEntity> sysUserEntityIPage = sysUserDao.queryUser(queryDTO);
            return Result.page(sysUserEntityIPage, queryUserDTOS(sysUserEntityIPage));
        }
        //根据code查询公司
        SysCompanyEntity sysCompanyEntity = sysCompanyDomainDao.queryCompanyAllByCode(userDTO.getCompanyCode());
        if (null != sysCompanyEntity) {

            if (sysCompanyEntity.getParentId() > 0) {
                userDTO.setCompanyCode(userDTO.getCompanyCode());
            } else {
                userDTO.setInitialCompanyCode(userDTO.getCompanyCode())
                        .setCompanyCode("");
            }
            queryDTO.setCondition(userDTO);
            IPage<SysUserEntity> sysUserEntityIPage = sysUserDao.queryUser(queryDTO);
            return Result.page(sysUserEntityIPage, queryUserDTOS(sysUserEntityIPage));
        }
        return Result.success();
    }

    public List<UserDTO> queryUserDTOS(IPage<SysUserEntity> sysUserEntityIPage) {
        return sysUserEntityIPage.getRecords().stream().map(sysUserEntity -> {
                    UserDTO userDTO = new UserDTO();
                    BeanUtils.copyProperties(sysUserEntity, userDTO);
                    SysDeptEntity sysDeptEntity = sysDeptDomainDao.queryDeptAllByCode(sysUserEntity.getDeptCode());

                    if (null != sysDeptEntity) {
                        userDTO.setDeptName(sysDeptEntity.getName());
                    }

                    SysCompanyEntity sysCompanyEntity = sysCompanyDomainDao.queryCompanyAllByCode(sysUserEntity.getCompanyCode());

                    if (null != sysCompanyEntity) {
                        userDTO.setCompanyName(sysCompanyEntity.getName());
                    }
                    userDTO.setPassword("");
                    return userDTO;
                }
        ).collect(Collectors.toList());
    }


    public Boolean saveUser(SysUserEntity sysUserEntity) {


        SysUserEntity userEntity = sysUserDao.queryUserDesc();
        if (null == sysUserEntity) {
            sysUserEntity.setAccount("100000000");
        } else if (StrUtil.isBlank(sysUserEntity.getAccount())) {
            Integer account = Integer.valueOf(userEntity.getAccount()) + 1;
            sysUserEntity.setAccount(String.valueOf(account));
        }


        userCompanyDeptCode(sysUserEntity);

        String newPassword = new BCryptPasswordEncoder().encode(sysUserEntity.getPassword());
        sysUserEntity.setPassword(newPassword);

        return sysUserDao.save(sysUserEntity);
    }


    public Boolean deleteUser(Integer id) {
        SysUserEntity sysUserEntity = sysUserDao.getById(id);

        sysUserEntity.setIsDeleted(IsDeletedEnum.DELETED.getValue());

        return sysUserDao.updateById(sysUserEntity);
    }

    public void userCompanyDeptCode(SysUserEntity sysUserEntity) {

        SysDeptEntity sysDeptEntity = sysDeptDomainDao.queryDeptByCode(sysUserEntity.getDeptCode());
        if (null != sysDeptEntity) {
            sysUserEntity
                    .setDeptCode(sysDeptEntity.getCode())
                    .setCompanyCode(sysDeptEntity.getCompanyCode());
            SysCompanyEntity sysCompanyEntity = sysCompanyDomainDao.queryCompanyByCode(sysUserEntity.getCompanyCode());
            sysUserEntity.setInitialCompanyCode(sysCompanyEntity.getParentCode());
        }
        //根据code查询公司
        SysCompanyEntity sysCompanyEntity = sysCompanyDomainDao.queryCompanyByCode(sysUserEntity.getDeptCode());
        if (null != sysCompanyEntity) {
            if (sysCompanyEntity.getParentId() > 0) {
                sysUserEntity
                        .setDeptCode("")
                        .setCompanyCode(sysCompanyEntity.getCode())
                        .setInitialCompanyCode(sysCompanyEntity.getParentCode());
            } else {
                sysUserEntity
                        .setDeptCode("")
                        .setInitialCompanyCode(sysCompanyEntity.getCode());
            }
        }

    }


    public SysUserEntity queryUserById(Integer id) {
        return sysUserDao.getById(id);
    }


    public Boolean updateUser(SysUserEntity sysUserEntity) {

        SysUserEntity userEntity = sysUserDao.getById(sysUserEntity.getId());

        if (StringUtils.isNotEmpty(sysUserEntity.getDeptCode())) {

            SysDeptEntity sysDeptEntity = sysDeptDomainDao.queryDeptByCode(sysUserEntity.getDeptCode());
            if (null != sysDeptEntity) {
                sysUserEntity
                        .setDeptCode(sysDeptEntity.getCode())
                        .setCompanyCode(sysDeptEntity.getCompanyCode());
                SysCompanyEntity sysCompanyEntity = sysCompanyDomainDao.queryCompanyByCode(sysUserEntity.getCompanyCode());
                sysUserEntity.setInitialCompanyCode(sysCompanyEntity.getParentCode());
            }
            //根据code查询公司
            SysCompanyEntity sysCompanyEntity = sysCompanyDomainDao.queryCompanyByCode(sysUserEntity.getDeptCode());
            if (null != sysCompanyEntity) {
                if (sysCompanyEntity.getParentId() > 0) {
                    sysUserEntity
                            .setDeptCode("")
                            .setCompanyCode(sysCompanyEntity.getCode())
                            .setInitialCompanyCode(sysCompanyEntity.getParentCode());
                } else {
                    sysUserEntity
                            .setDeptCode("")
                            .setCompanyCode("")
                            .setInitialCompanyCode(sysCompanyEntity.getCode());
                }
            }
            if (null == sysDeptEntity && null == sysCompanyEntity) {
                sysUserEntity.setDeptCode(userEntity.getDeptCode())
                        .setCompanyCode(userEntity.getCompanyCode())
                        .setInitialCompanyCode(userEntity.getInitialCompanyCode());
            }
        } else {
            sysUserEntity.setDeptCode(userEntity.getDeptCode())
                    .setCompanyCode(userEntity.getCompanyCode())
                    .setInitialCompanyCode(userEntity.getInitialCompanyCode());
        }
        userEntity.setAccount(sysUserEntity.getAccount());
        userEntity.setName(sysUserEntity.getName());
        userEntity.setStatus(sysUserEntity.getStatus());
        userEntity.setPhone(sysUserEntity.getPhone());
        userEntity.setSex(sysUserEntity.getSex());
        userEntity.setAvatar(sysUserEntity.getAvatar());
        userEntity.setWorkOn(sysUserEntity.getWorkOn());
        userEntity.setNickName(sysUserEntity.getNickName());
        userEntity.setDeptCode(sysUserEntity.getDeptCode());
        userEntity.setCompanyCode(sysUserEntity.getCompanyCode());
        userEntity.setInitialCompanyCode(sysUserEntity.getInitialCompanyCode());
        return sysUserDao.updateById(userEntity);
    }


    public Boolean updatePassword(ResetPasswordDTO resetPasswordDTO) {

        SysUserEntity sysUserEntity = sysUserDao.getById(resetPasswordDTO.getUserId());

        if (null != sysUserEntity) {
            throw new RuntimeException("用户不存在");
        }

        if (sysUserEntity.getAccount().equals(resetPasswordDTO.getAccount())) {
            throw new RuntimeException("用户账号不一致");
        }

        String newPassword = new BCryptPasswordEncoder().encode(resetPasswordDTO.getPassword());
        sysUserEntity.setPassword(newPassword);

        return sysUserDao.updateById(sysUserEntity);
    }


    public LoginVO userLogin(UserLoginDTO userLoginDTO) {

        SysUserEntity user = queryUserByAccount(userLoginDTO.getAccount(), userLoginDTO.getSystemId());
        if (null == user) {
            throw new RuntimeException("用户不存在");
        }

        if (!StatusEnum.ENABLE.getValue().equals(user.getStatus())) {
            throw new RuntimeException("用户被禁用");
        }
        userLoginDTO.getPassword();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (!passwordEncoder.matches(userLoginDTO.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户密码错误");
        }

        //RoleUserDTO roleUserDTO = roleUserDomainDao.queryRolesByUserId(user.getId());


        LoginVO loginVO = new LoginVO();
        String token = jwtUtils.getJwtTokenByEmail(
                String.valueOf(user.getId()),
                user.getAccount(),
                user.getName(),
                SystemIdEnum.HUANG_HE.getValue().equals(user.getSystemId()),
                user.getSystemId(),
                user.getCustomerId(),
                user.getCustomerAdmin()
        );
        loginVO.setId(user.getId())
                .setAccount(user.getAccount())
                .setName(user.getName())
                .setToken(token)
                .setSystemId(user.getSystemId())
                .setCustomerId(user.getCustomerId())
                .setCustomerAdmin(user.getCustomerAdmin());
        return loginVO;
    }

    public SysUserEntity queryUserByAccount(String account, Integer systemId) {

        List<SysUserEntity> sysUserEntities = sysUserDao.queryUserByAccount(account, systemId);

        return sysUserEntities.isEmpty() ? null : sysUserEntities.get(0);
    }

    public Boolean updateUserStatus(Integer id) {

        SysUserEntity sysUserEntity = sysUserDao.getById(id);

        if (StatusEnum.ENABLE.getValue().equals(sysUserEntity.getStatus())) {

            sysUserEntity.setStatus(StatusEnum.DISABLE.getValue());
        } else {
            sysUserEntity.setStatus(StatusEnum.ENABLE.getValue());

        }

        return sysUserDao.updateById(sysUserEntity);
    }


    public String generateCompanyCode(String companyCode) {

        String code;

        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(companyCode)) {
            String code1 = companyCode.substring(1, companyCode.length());
            code = "D" + (Integer.parseInt(code1) + 1);
        } else {

            code = "D00001";
        }


        return code;
    }

    public UserPermissionMenuDTO queryUserPremiseMenu(Integer id) {

        UserPermissionMenuDTO userPermissionMenuDTO = new UserPermissionMenuDTO();

        List<SysRoleUserEntity> roleUserEntities = sysRoleUserDomainDao.queryByUserId(id);
        List<String> roleCodeList = roleUserEntities.stream().map(SysRoleUserEntity::getRoleCode).distinct().collect(Collectors.toList());
        List<String> permissionList = sysRolePermissionDomainDao.queryPermissionListByRoleCodeList(roleCodeList);
        List<SysMenuEntity> menuEntityList = new ArrayList<>();
        if (!roleCodeList.isEmpty()) {
            menuEntityList = sysMenuDomainDao.getMenuListByRoleCodeList(roleCodeList);
        }


        return userPermissionMenuDTO
                .setPermissionCodeList(permissionList)
                .setRoleCodeList(roleCodeList)
                .setSysMenuEntities(menuEntityList);
    }

    /**
     * 下拉选择
     *
     * @return
     */
    public List<Tree<Integer>> querySelect() {
        List<SysUserEntity> list = sysUserDao.list(SysUserEntity.gw()
                        .eq(SysUserEntity::getSystemId,1).select(FunongBaseEntity::getId, SysUserEntity::getName, SysUserEntity::getPhone));
        List<Tree<Integer>> result = new ArrayList<>();
        list.forEach(item -> {
            Tree tree = new Tree().setId(item.getId()).setName(item.getName());
            tree.putExtra("phone", item.getPhone());
            result.add(tree);
        });
        return result;
    }

    /**
     * 根据权限编码获取用户列表信息
     * @param permissionCode
     * @return
     */
    public List<SysUserEntity>   queryUserByPermission(String permissionCode) {
        return sysUserDao.queryUserByPermission(permissionCode);
    }
}
